package com.server.common.mybatis.handler;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.List;

@Intercepts({})
@Component
public class MyBatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        }else if (target instanceof DefaultParameterHandler) {
            DefaultParameterHandler defaultParameterHandler = (DefaultParameterHandler) target;
//            try {
//                //获取mappedStatement
//                Field mappedStatementField = DefaultParameterHandler.class.getDeclaredField("mappedStatement");
//                mappedStatementField.setAccessible(true);
//                MappedStatement mappedStatement = (MappedStatement) mappedStatementField.get(defaultParameterHandler);
//
//                //获取boundSql
//                Field boundSqlField = DefaultParameterHandler.class.getDeclaredField("boundSql");
//                boundSqlField.setAccessible(true);
//                BoundSql boundSql = (BoundSql) boundSqlField.get(defaultParameterHandler);
//
//                //参数注入
//                List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//
//
//                //获取resultMap
//                ResultMap resultMap = mappedStatement.getResultMaps().get(0);
//                String name = resultMap.getType().getName();
//
//                //获取返回实体类Vo
//                Class<?> voClass = Class.forName(name);
//                Field[] declaredFields = voClass.getDeclaredFields();
//
//                if(ObjectUtils.isEmpty(declaredFields)){
//                    return Plugin.wrap(target, this);
//                }
//
//                //获取返回VO实体类读取，拼接
//                String sql = boundSql.getSql();
//                StringBuilder sqlReturnString = new StringBuilder();
//                int number = 0;
//                for (Field field:declaredFields){
//                    field.setAccessible(true);
//                    ReturnField returnField = field.getAnnotation(ReturnField.class);
//                    if(ObjectUtils.isEmpty(returnField)){
//                        continue;
//                    }
//                    String tableAlias = StrUtil.toCamelCase(returnField.table().getValue());
//
//                    if(number != 0){
//                        sqlReturnString.append(",");
//                    }
//
//                    if(!ObjectUtils.isEmpty(tableAlias)){
//                        sqlReturnString.append(tableAlias).append(".");
//                    }
//                    sqlReturnString.append(StrUtil.toUnderlineCase(field.getName()));
//                    number++;
//                }
//
//                if(number == 0){
//                    return Plugin.wrap(target, this);
//                }
//
//                sql = sql.replace("{vos}",sqlReturnString.toString());
//
//                //注入sql
//                Field sqlField = BoundSql.class.getDeclaredField("sql");
//                sqlField.setAccessible(true);
//                sqlField.set(boundSql,sql);
//            } catch (Exception e) {
//                log.error("注入失败",e);
//            }
            return Plugin.wrap(target, this);
        }else if (target instanceof DefaultResultSetHandler) {
            return Plugin.wrap(target, this);
        }
        return Interceptor.super.plugin(target);
    }
}
